﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Fluq;

namespace Fluq.Tests
{
	public interface IMock
	{
		void OnDispose(object transparentProxy);

		void OnCreated(object transparentProxy);
	}

	public class Mock<TType> : Mock
	{
		public Mock(IDependency dependency)
			: base(dependency, typeof(TType))
		{
		}
	}

	public class Mock : IMock, IDependency
	{
		private IDependency _dependency;
		private int _numberOfDisposals;
		private int _numberOfCreations;
		private int _numberOfInstances;
		private Type _abstractType;

		public Mock(IDependency dependency, Type abstractType)
		{
			_dependency = dependency;
			_abstractType = abstractType;
		}

		public int NumberOfDisposals { get { return _numberOfDisposals; } }

		public int NumberOfCreations { get { return _numberOfCreations; } }

		public int NumberOfInstances { get { return _numberOfInstances; } }

		public void OnDispose(object transparentProxy)
		{
			_numberOfDisposals++;
			_numberOfInstances--;
		}

		public void OnCreated(object transparentProxy)
		{
			_numberOfCreations++;
			_numberOfInstances++;
		}

		Func<IDependencyContainer, IEnumerable<IDependencyParameter>, object> IDependency.Factory
		{
			get
			{
				return (c, p) =>
				{
					object o = _dependency.Factory(c, p);

					if (o != null)
					{
						MockProxy proxy = new MockProxy(o, _abstractType, this);

						o = proxy.GetTransparentProxy();

						OnCreated(o);
					}

					return o;
				};
			}
		}

		IDependencyKey IDependency.Key { get { return _dependency.Key; } }

		IDependencyLifestyle IDependency.Lifestyle { get { return _dependency.Lifestyle; } }

		public Action<object> Disposer { get { return instance => { }; } }

		public IEnumerable<IDependencyParameter> Parameters { get { yield break; } }
	}
}
